package org.jeecg.modules.app.login.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.WxMaUserService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import me.chanjar.weixin.common.error.WxErrorException;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.ApiLogin;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.miniapp.AliConfig;
import org.jeecg.modules.app.login.service.ProgramLoginService;
import org.jeecg.modules.app.util.AesCbcUtil;
import org.jeecg.modules.app.util.AliPayConfig;
import org.jeecg.modules.power.user.entity.YlUser;
import org.jeecg.modules.power.user.service.IYlUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * @BelongsProject: jeecg-boot-parent
 * @BelongsPackage: org.jeecg.modules.app.login.controller
 * @Author: mi
 * @CreateTime: 2024-07-09 16:03
 * @Description:
 */
@CrossOrigin
@Api(tags = "小程序登陆相关接口")
@RestController
@RequestMapping("/api/programLogin")
public class ProgramLogin {



    @Resource
    private WxMaUserService wxMaUserService;


    @Autowired
    private ProgramLoginService programLoginService;


    @Autowired
    private   AliConfig aliConfig;//支付宝

    @Autowired
    private IYlUserService ylUserService;//用户表


    @ApiOperation(value="微信小程序授权登陆", notes="微信小程序授权登陆")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "code", required = true),
            @ApiImplicitParam(name = "encryptedData", value = "秘钥", required = true),
            @ApiImplicitParam(name = "iv", value = "偏移量", required = true),
    })
    @PostMapping(value = "/wxCodeLogin")
    public Result<?> wxCodeLogin(String code,String encryptedData, String iv) throws WxErrorException {
        if (oConvertUtils.isEmpty(code))return Result.error_599("code不可为空");
        if (oConvertUtils.isEmpty(encryptedData))return Result.error_599("秘钥不可为空");
        if (oConvertUtils.isEmpty(iv))return Result.error_599("偏移量的不可为空");
        WxMaJscode2SessionResult session =   wxMaUserService.getSessionInfo(code);
        if(null==session || oConvertUtils.isEmpty(session.getOpenid()) || oConvertUtils.isEmpty(session.getSessionKey())){
            return Result.error_599("微信授权失败");
        }
        String openid= session.getOpenid();
        String sessionKey= session.getSessionKey();
        String unionId =session.getUnionid();

//        System.out.println(session.getOpenid());
//        System.out.println(session.getSessionKey());
//        System.out.println(session.getUnionid()); programLoginService addYlUser(YlUser ylUser);
        YlUser ylUser = new YlUser();
        ylUser.setUnionid(unionId);
        ylUser.setOpenid(openid);
        ylUser.setSource(0);//0微信 1支付宝
        ylUser.setIsMember(0);//是否是会员0否1是

        //判定 是不是第一次授权登陆
//        Integer  userLogin= ylUserService.count(new LambdaQueryWrapper<YlUser>().eq(YlUser::getUnionid,ylUser.getUnionid()));
        YlUser ifUser= ylUserService.getOne(new LambdaQueryWrapper<YlUser>().eq(YlUser::getUnionid,ylUser.getUnionid()));
        if (oConvertUtils.isEmpty(ifUser)){
            //只有第一次 授权登陆 才去获取手机号
            String userInfo  = AesCbcUtil.decrypt(encryptedData, sessionKey, iv, "UTF-8");//解密 获取手机号
            JSONObject userInfoJson = JSONObject.parseObject(userInfo);
            if (oConvertUtils.isNotEmpty( userInfoJson.getString("phoneNumber"))){
                ylUser.setTel( userInfoJson.getString("phoneNumber"));//用户手机号
            }else {
                return Result.error_599("获取手机号失败");
            }
        }else {
            if (ifUser.getStatus()==2){
                return Result.error_599("此账号已被冻结 请联系管理员");
            }
        }
        return  programLoginService.addYlUser(ylUser);
    }









    //支付宝 授权登陆 证书版
    @ApiOperation(value="支付宝授权登陆", notes="支付宝授权登陆")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "code", required = true),
    })
    @PostMapping(value = "/aliCodeLogin")
    public Result<?>aliCodeLogin(String code) throws AlipayApiException {
        if (oConvertUtils.isEmpty(code))return Result.error_599("code不可为空");

        String accessToken="";//accessToken
        String uid="";//支付宝用户id
        String nickName="";//支付宝用户昵称
        String avatar="";//支付宝头像

//        System.out.println(aliConfig.getAppId()+"=====");
        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        certAlipayRequest.setServerUrl(AliPayConfig.gatewayUrl);
        certAlipayRequest.setAppId(aliConfig.getAppId());//支付宝用户
        certAlipayRequest.setPrivateKey(AliPayConfig.merchant_private_key);//应用 私钥
        certAlipayRequest.setFormat("json");
        certAlipayRequest.setCharset("UTF-8");
        certAlipayRequest.setSignType("RSA2");
        certAlipayRequest.setCertPath(aliConfig.getCertPath());
        certAlipayRequest.setAlipayPublicCertPath(aliConfig.getPublicCertPath());
        certAlipayRequest.setRootCertPath(aliConfig.getRootCertPath());

        AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
         //授权方式。支持：
        //authorization_code：使用应用授权码换取应用授权令牌app_auth_token。
        //refresh_token：使用app_refresh_token刷新获取新授权令牌。
        request.setGrantType("authorization_code");
        request.setCode(code);

        AlipaySystemOauthTokenResponse response = alipayClient.certificateExecute(request);
        if(response.isSuccess()){
            accessToken=response.getAccessToken();
            uid=response.getUserId();
        } else {
            return Result.error_599("调用失败");
        }
        /** 获取接口调用结果 **/
        System.out.println(response.getBody());
        //获取用户信息
        /** 实例化具体API对应的request类，类名称和接口名称对应,当前调用接口名称 alipay.user.info.share(支付宝会员授权信息查询接口) **/
        AlipayUserInfoShareRequest req = new AlipayUserInfoShareRequest();
        //用户授权令牌，同 access_token（用户访问令牌）。针对用户授权接口，获取用户相关数据时，用于标识用户授权关系。需使用 auth_code（用户授权码）换取此令牌
        request.putOtherTextParam("auth_token", accessToken);
//        AlipayUserInfoShareResponse resp = alipayClient.certificateExecute(req);
        AlipayUserInfoShareResponse resp = alipayClient.execute(req);
        /** 获取接口调用结果 **/
        System.out.println(resp.getBody());
        return Result.OK("等待开发");
    }







    //小程序退出登陆
    @ApiLogin
    @ApiOperation("小程序用户退出登陆")
    @PostMapping("userQuit")
    public Result<?>userQuit(HttpServletRequest request){
        String token = request.getHeader("token"); // 从 http 请求头中取出 token  token
        return  programLoginService.userQuit(token);
    }















}
